<template>
  <div class="wrapper clearFix">
    <!-- 组件区 -->
    <section id="comp-panel" class="panel" @dragstart="dragStart" @dragend="dragEnd">
      <comp-panel/>
    </section>

    <!-- 预览区 -->
    <section id="preview-panel" class="panel ml10">
      <preview-panel :comp-list="compList"
                     :preview-list.sync="previewList"
                     @dropEmit="drop"
                     @dragOverEmit="dragOver"
      />
    </section>

    <!-- 属性区 -->
    <section id="param-panel" class="panel ml10"></section>
  </div>
</template>

<script>
  import CompList from '@/templateComps/index'
  import CompPanel from "@/page/components/CompPanel";
  import PreviewPanel from "@/page/components/PreviewPanel";

  export default {
    name: "index",
    components: {
      CompPanel, PreviewPanel
    },
    provide() {
      return {
        compList: this.compList
      }
    },
    data() {
      return {
        compList: CompList, // 可供拖拽的所有组件
        previewList: [], // 预览区的所有组件
        dragCompType: null, // 当前拖拽组件的类型
        dragCompName: null, // 当前拖拽组件名
        isPushed: false,      // 组件是否已被添加
        index: null,        // 当前组件的索引
        isDragging: false, // 是否拖拽中
      };
    },
    methods: {
      // 创建预览区列表的数据
      createPreviewItemData() {
        return {
          name: this.dragCompName, // 组件名称
          type: this.dragCompType, // 组件类型
          dragging: true, // 是否拖拽中,拖拽结束将删除此属性
          children: [], // 组件子集
          params: {}, // 组件参数
        }
      },

      // 拖拽移动中
      dragOver(e) {
        if (!this.dragCompType) return

        this.stopDefEvents(e)

        let target = e.target
        let className = target.className || ''
        let name = className !== 'preview-cont' ? 'preview-item' : 'preview-cont'

        let defaultData = this.createPreviewItemData()

        if (this.dragCompType === 'layout') {
          defaultData.children = [
            {
              name: 'CompButton', // 组件名称
              type: 'button', // 组件类型
              dragging: false, // 是否拖拽中,拖拽结束将删除此属性
              children: [], // 组件子集
              params: {} // 组件参数
            }
          ]
        }

        if (name === 'preview-cont') {
          if (!this.isPushed) {
            this.index = this.previewList.length
            this.isPushed = true
            this.previewList.push(defaultData)
          }
        } else if (name === 'preview-item') {
          let curIndex = parseInt(target.dataset.index) || 0 // 当前元素的index值
          let offsetY = e.offsetY // 距离目标元素的垂直高度
          let offsetHeight = target.offsetHeight // 目标元素的高度
          // 判断拖动元素是否在目标元素的上半区
          let topOfTarget = offsetY < (offsetHeight / 2)

          if (!this.isPushed) {
            if (topOfTarget) {
              if (curIndex == 0) {
                this.previewList.unshift(defaultData)
              } else {
                this.previewList.splice(curIndex, 0, defaultData)
              }
            } else {
              curIndex = curIndex + 1
              this.previewList.splice(curIndex, 0, defaultData)
            }
          } else {
            // 移动中
            let result
            if (topOfTarget) {
              let i = curIndex == 0 ? 0 : curIndex - 1
              result = this.previewList[i]['dragging']
            } else {
              let i = curIndex + 1
              result = this.previewList.length > i && this.previewList[i]['dragging']
            }

            if (result) return

            const temp = this.previewList.splice(this.index, 1)
            this.previewList.splice(curIndex, 0, temp[0])
          }
          this.index = curIndex
          this.isPushed = true
        }
      },

      // 拖拽移动中
      // dragOver(e) {
      //   if (!this.dragCompType) return
      //
      //   this.stopDefEvents(e)
      //
      //   let className = e.target.className || ''
      //   let name = className !== 'preview-cont' ? 'preview-item' : 'preview-cont'
      //
      //   let defaultData = {
      //     name: this.dragCompName, // 组件名称
      //     type: this.dragCompType, // 组件类型
      //     dragging: true, // 是否拖拽中,拖拽结束将删除此属性
      //     children: [], // 组件子集
      //     params: {}, // 组件参数
      //   }
      //
      //   if (this.dragCompType === 'layout') {
      //     defaultData.children = [
      //       {
      //         name: 'CompButton', // 组件名称
      //         type: 'button', // 组件类型
      //         dragging: false, // 是否拖拽中,拖拽结束将删除此属性
      //         children: [], // 组件子集
      //         params: {} // 组件参数
      //       },
      //       {
      //         name: 'CompInput', // 组件名称
      //         type: 'input', // 组件类型
      //         dragging: false, // 是否拖拽中,拖拽结束将删除此属性
      //         children: [], // 组件子集
      //         params: {} // 组件参数
      //       }
      //     ]
      //   }
      //
      //   if (name === 'preview-cont') {
      //     if (!this.isPushed) {
      //       this.index = this.previewList.length
      //       this.isPushed = true
      //       this.previewList.push(defaultData)
      //     }
      //   } else if (name === 'preview-item') {
      //     let target = e.target
      //     let [y, h, curIndex] = [e.offsetY, target.offsetHeight, parseInt(target.dataset.index) || 0]
      //     // 是否在元素的高度的一半以下，如果true就添加在该元素下方，否则上方
      //     let direction = y < (h / 2)
      //
      //     if (!this.isPushed) {
      //       if (direction) {
      //         if (curIndex == 0) {
      //           this.previewList.unshift(defaultData)
      //         } else {
      //           this.previewList.splice(curIndex, 0, defaultData)
      //         }
      //       } else {
      //         curIndex = curIndex + 1
      //         this.previewList.splice(curIndex, 0, defaultData)
      //       }
      //     } else {
      //       // 移动中
      //       let result
      //       if (direction) {
      //         let i = curIndex == 0 ? 0 : curIndex - 1
      //         result = this.previewList[i]['dragging']
      //       } else {
      //         let i = curIndex + 1
      //         result = this.previewList.length > i && this.previewList[i]['dragging']
      //       }
      //
      //       if (result) return
      //
      //       const temp = this.previewList.splice(this.index, 1)
      //       this.previewList.splice(curIndex, 0, temp[0])
      //     }
      //     this.index = curIndex
      //     this.isPushed = true
      //   }
      // },

      // 拖拽开始
      dragStart(e) {
        this.dragCompType = e.target.dataset.type
        this.dragCompName = e.target.dataset.name
        this.isDragging = true
      },

      // 拖拽结束
      dragEnd() {
        this.$delete(this.previewList[this.index], 'dragging')
        this.isPushed = false
        this.dragCompType = null
        this.isDragging = false
      },

      // 拖拽放下
      drop(e) {
        if (!this.dragCompType) return
        this.stopDefEvents(e)
        this.dragEnd()
      },

      // 阻止默认事件和冒泡事件
      stopDefEvents(e) {
        e.preventDefault()
        e.stopPropagation()
      },
    }
  }
</script>

<style scoped lang="scss">
  .wrapper {
    background: #f7f8f9;
    padding: 10px;
    width: calc(100% - 20px);
    height: calc(100% - 20px);

    .panel {
      overflow: hidden;
      float: left;
      padding: 10px;
      height: calc(100% - 20px);
      border-radius: 5px;
      box-shadow: 0 2px 12px 0 rgb(0 0 0 / 10%);
      background: #FFF;
    }

    #comp-panel, {
      width: 280px;
    }

    #param-panel {
      width: 380px;
    }

    #preview-panel {
      width: calc(100% - 280px - 380px - 60px - 20px);
    }
  }
</style>